package com.gmics.unifiq;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.location.Location;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.gmics.android.R;
import com.gmics.unifiq.controller.AlertDialogManager;
import com.gmics.unifiq.controller.EntityController;
import com.gmics.unifiq.controller.GPSTracker;
import com.gmics.unifiq.controller.UserFunctions;
import com.gmics.unifiq.entity.Avatar;
import com.gmics.unifiq.entity.CheckIn;
import com.gmics.unifiq.entity.OpenEvent;
import com.gmics.unifiq.entity.User;
import com.gmics.unifiq.entity.UserNotification;

public class ViewOpenEvent extends Activity {
	private EntityController controller = new EntityController();
	private OpenEvent currentOE;
	private int contextMenuBase = 300;
	private TextView titleTV, locationTV, dateTimeTV, capacityTV, descTV;
	private Button actionBtn;
	private ImageButton locationIcon;
	private int[] imgArr = { R.drawable.blue_square_large,
			R.drawable.red_square_large, R.drawable.green_square_large,
			R.drawable.orange_square_large };
	private ImageView imgHolder;
	private static int MAX_DAYS = 3;
	private int userID, tabPos = 0;
	private ArrayList<Integer> userIDArr;
	private AlertDialogManager alert = new AlertDialogManager();
	private static double MAX_DISTANCE = 1000; // meters
	private User currentUser;
	
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		if (item.getItemId() == contextMenuBase) {
			Intent mapScreen = new Intent(this, ViewMap.class);
			mapScreen.putExtra("location", currentOE.getLocation());
			startActivity(mapScreen);
			return true;
		} else if (item.getItemId() == contextMenuBase + 1) {
			Intent addressScreen = new Intent(this, ViewAddress.class);
			addressScreen.putExtra("location", currentOE.getLocation());
			startActivity(addressScreen);
			return true;
		}
		return false;
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.view_open_event_layout);

	    if (android.os.Build.VERSION.SDK_INT > 9) {
	        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
	        StrictMode.setThreadPolicy(policy);
	      }
	    
		Bundle b = getIntent().getExtras();
		currentOE = (OpenEvent) b.getSerializable("selectedOpenEvent");
		int imgPos = b.getInt("imgPos");
		tabPos = b.getInt("tabPos");
		
		UserFunctions uf = new UserFunctions();
		HashMap<String, String> user = uf.getUser(this);
		currentUser = controller.retrieveUser(user.get("uid"));
		
		userID = currentUser.getId();
		
		ArrayList<ArrayList<Integer>> idArr = controller.retrieveOpenEventAttendance(currentOE.getId(), 0);
		userIDArr = idArr.get(1);
		
		imgHolder = (ImageView) findViewById(R.id.img_holder);
		titleTV = (TextView) findViewById(R.id.title_tv);
		locationTV = (TextView) findViewById(R.id.location_tv);
		dateTimeTV = (TextView) findViewById(R.id.date_time_tv);
		capacityTV = (TextView) findViewById(R.id.capacity_tv);
		descTV = (TextView) findViewById(R.id.desc_tv);
		actionBtn = (Button) findViewById(R.id.action_btn);
		locationIcon = (ImageButton) findViewById(R.id.location_icon);
		
		imgHolder.setBackgroundResource(imgArr[imgPos]);
		titleTV.setText(currentOE.getName());
		locationTV.setText(currentOE.getLocation());
		capacityTV.setText(String.valueOf(userIDArr.size()) + "/" + String.valueOf(currentOE.getCapacity()));
		dateTimeTV.setText(EntityController.convertDateTimeToFullString(currentOE
				.getDateTime()));
		descTV.setText(currentOE.getDescription());
		
		locationIcon.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				Intent viewEventMapScreen = new Intent(ViewOpenEvent.this, ViewEventMap.class);
				viewEventMapScreen.putExtra("location", currentOE.getLocation());
				startActivity(viewEventMapScreen);
			}
			
		});
		
		Date eventDate = EntityController.dateTimeToDate(currentOE.getDateTime());
		Date currentDate = EntityController.dateTimeToDate(Calendar.getInstance().getTime());
		
		long diffDays = (eventDate.getTime() - currentDate.getTime()) / (24 * 60 * 60 * 1000);

		if (eventDate.compareTo(currentDate) > 0 && diffDays > MAX_DAYS){
			boolean valid = false;
			for (int i = 0; i < userIDArr.size(); i++){
				if (userIDArr.get(i) == userID){
					valid = true;
					break;
				}
			}
			

			
			if (!valid && userIDArr.size() != currentOE.getCapacity()){
				actionBtn.setVisibility(Button.VISIBLE);
				actionBtn.setText("Sign up");
				actionBtn.setOnClickListener(new OnClickListener(){
	
					@Override
					public void onClick(View arg0) {
						// TODO Auto-generated method stub
						if (controller.createOpenEventAttendance(currentOE.getId(), userID)){
							alert.showAlertDialog(ViewOpenEvent.this, "Sign-up successful",
									"You have signed up for " + currentOE.getName() + ".",
									true);
							capacityTV.setText(String.valueOf(userIDArr.size() + 1) + "/" + String.valueOf(currentOE.getCapacity()));
							actionBtn.setVisibility(Button.INVISIBLE);
						}
						else{
							alert.showAlertDialog(ViewOpenEvent.this, "Sign-up unsuccessful",
									"We were unable to sign up for you at this moment. Please try again later.",
									false);
						}
					}
					
				});
			}
		}
		
		if (tabPos == 1){
			actionBtn.setText("Check-in now!");
			actionBtn.setVisibility(Button.VISIBLE);
			actionBtn.setOnClickListener(new OnClickListener(){

				@Override
				public void onClick(View arg0) {
					// TODO Auto-generated method stub
					GPSTracker gps = new GPSTracker(ViewOpenEvent.this);

					if (gps.canGetLocation() && gps.getLatitude() != 0 && gps.getLongitude() != 0) {
						Location currentLocation = new Location("currentLocation");
						currentLocation.setLatitude(gps.getLatitude());
						currentLocation.setLongitude(gps.getLongitude());
						Location eventLocation = new Location("eventLocation");
						eventLocation.setLatitude(currentOE.getLatitude());
						eventLocation.setLongitude(currentOE.getLongitude());
						
						if (currentLocation.distanceTo(eventLocation) < MAX_DISTANCE){
							if (controller.createCheckin(userID, currentOE.getId(), 0)){
								
								boolean pointsSuccess = controller.createNotification(currentOE.getId(), 0, "Obtained Loyalty Points", "You have just gained 10 loyalty points for checking in for " + currentOE.getName() + ".");
					        	int pointsID = controller.retrieveLatestNotification().getId();
								boolean userPointsSuccess = controller.createUserNotification(pointsID, userID);
								
								if (pointsSuccess && userPointsSuccess){
									alert.showAlertDialog(ViewOpenEvent.this, "Check-in successful",
											"You have checked in for " + currentOE.getName() + " and gained 10 loyalty points.",
											true);
									actionBtn.setVisibility(Button.INVISIBLE);
								}
								
					        	ArrayList<CheckIn> checkInArr = controller.retrieveCheckIn(userID);
					        	ArrayList<Avatar> avatarArr = controller.retrieveAvatarFilter(checkInArr.size());
					        	for (int i = 0; i < avatarArr.size(); i++){
					        		if (checkInArr.size() == avatarArr.get(i).getRequirement()){
					        			
		            					boolean notificationSuccess = controller.createNotification(0, 0, "Unlocked Avatar", "You have just unlocked " + avatarArr.get(i).getName() + " for attending " + String.valueOf(avatarArr.get(i).getRequirement()) + " and more events!");
		            					boolean userNotificationSuccess = false;
		            					
		            					if (notificationSuccess){
		            						int notificationID = controller.retrieveLatestNotification().getId();
		            						userNotificationSuccess = controller.createUserNotification(notificationID, userID);
		            					}
		            					
		            					if (userNotificationSuccess){
		            						ArrayList<UserNotification> unArr = controller.retrieveUserNotification(userID);
		            						int unread = 0;
		            						for (int a = 0; a < unArr.size(); a++){
		            							if (!unArr.get(a).isRead()){
		            								unread++;
		            							}
		            						}
		            						
		            						if (unread != 0){
		            							Avatar avatar = controller.retrieveAvatar(currentUser.getAvatarID());
		            							LayoutInflater inflater = ViewOpenEvent.this.getLayoutInflater();
		            							View layout = inflater.inflate(R.layout.avatar_toast,
							                               (ViewGroup) ViewOpenEvent.this.findViewById(R.id.avatar_toast_ll));
		            							TextView avatarText = (TextView) layout.findViewById(R.id.avatar_tv);
		            							ImageView avatarIcon = (ImageView) layout.findViewById(R.id.avatar_icon);
		            							
		            							Bitmap bm = null;
		            							
		            							try {
		            								 URL url = new URL(avatar.getIconPath()); 
		            								 HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		            								 connection.setRequestMethod("POST");
		            								 connection.setRequestProperty("Connection", "close"); 
		            								 connection.connect();
		            								 bm = BitmapFactory.decodeStream(connection.getInputStream());		
		            							} catch (MalformedURLException e) {
		            								// TODO Auto-generated catch block
		            								e.printStackTrace();
		            							} catch (IOException e) {
		            								// TODO Auto-generated catch block
		            								e.printStackTrace();
		            							}	
		            							
		            							avatarIcon.setImageBitmap(bm);
		            							avatarText.setText("You have " + String.valueOf(unread) + " pending notifications!");
		            		
		            							Toast toast = new Toast(ViewOpenEvent.this.getApplicationContext());
		            							toast.setDuration(Toast.LENGTH_LONG);
		            							toast.setView(layout);
		            							toast.show();
		            						}
		            						
		            					}
					        		}
					        	}
							}
							else{
								alert.showAlertDialog(ViewOpenEvent.this, "Check-in unsuccessful",
										"We were unable to check in for you at this moment. Please try again later.",
										false);
							}

						}
						else{
							alert.showAlertDialog(ViewOpenEvent.this, "Not near event location",
									"Unable to check in: You're not within 1km of the event location.",
									false);
						}

					} else {
						alert.showAlertDialog(ViewOpenEvent.this, "GPS Status",
								"Couldn't get location information. Please enable GPS.",
								false);
					}
				}
				
			});
		}
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		menu.setHeaderTitle("View via...");
		menu.add(contextMenuBase, contextMenuBase, contextMenuBase, "Map");
		menu.add(contextMenuBase, contextMenuBase + 1, contextMenuBase + 1,
				"Address");
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}